package com.codefish.framework.spring.aop.aspectj;

import com.codefish.framework.spring.aop.IClassFilter;
import com.codefish.framework.spring.aop.IMethodMatcher;
import com.codefish.framework.spring.aop.support.AbstractExpressionPointcut;
import com.codefish.framework.spring.core.utils.AssertUtils;
import org.aspectj.weaver.tools.PointcutExpression;
import org.aspectj.weaver.tools.PointcutParser;

import java.lang.reflect.Method;

/**
 * @author <a href='https://gitee.com/hzf2281'>codefish</a>
 * @version 1.0.0
 * @since 2022/10/13 下午 03:40
 */
public class AspectJExpressionPointcut extends AbstractExpressionPointcut implements IClassFilter, IMethodMatcher {


    private PointcutExpression pointcutExpression;


    public AspectJExpressionPointcut(String expression) {
        setExpression(expression);
        buildPointcutExpression(getExpression());
    }

    private void buildPointcutExpression(String expression) {
        if (pointcutExpression == null) {
            AssertUtils.notNull(expression, "切点表达式不能为null");
            PointcutParser parser = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingContextClassloaderForResolution();
            this.pointcutExpression = parser.parsePointcutExpression(expression);
        }
    }


    @Override
    public IClassFilter getClassFilter() {
        return this;
    }

    @Override
    public IMethodMatcher getMethodMatcher() {
        return this;
    }

    @Override
    public boolean matches(Class<?> clazz) {
        return pointcutExpression.couldMatchJoinPointsInType(clazz);
    }

    @Override
    public boolean matches(Method method, Class<?> targetClazz) {
        if (!matches(targetClazz)) {
            return false;
        }
        return pointcutExpression.matchesMethodExecution(method).alwaysMatches();
    }
}
